#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include "ir_Haier.h"
#include "IRutils.h"
#include "driver/rmt_tx.h" // RMT发送功能（用于红外发送）

// 扩展功能标识
#define HAIER_EXTEND_HEALTH 0x01
#define HAIER_EXTEND_SLEEP  0x02
#define HAIER_EXTEND_TURBO  0x04
#define HAIER_EXTEND_QUIET  0x08
#define HAIER_EXTEND_LOCK   0x10
#define HAIER_EXTEND_SWINGV 0x20
#define HAIER_EXTEND_SWINGH 0x40

//HaierAcYrw02头尾和结束符占RMT符号数
#define HAIER_ACYRW02_HEAD_AND_TAIL_SYMBOLS (3+3+1)

static rmt_symbol_word_t *out_symbols = NULL; // 存储转换后的RMT符号数据


typedef struct {
    Air_conditioner_t ac;
    union HaierAc176Protocol ac176;
} HaierAcYrw02_t, *pHaierAcYrw02_t;
/*********************************************/

/**
 * @brief 获取当前设置的温度（辅助函数，模拟原逻辑中的getTemp()）
 * @param pAC 空调设备指针
 * @return 当前温度值（摄氏度或华氏度，取决于当前单位）
 */
static uint8_t haier_acyrw02_get_temp(pAir_conditioner_t pAC)
{
    pHaierAcYrw02_t pHaier = (pHaierAcYrw02_t)pAC;
    if (pHaier->ac176.UseFahrenheit) {
        uint8_t degree = pHaier->ac176.Temp * 2 + kHaierAcYrw02MinTempF + pHaier->ac176.ExtraDegreeF;
        // 修正原逻辑中的特殊温度偏移
        if (degree >= 77)
            degree--;
        if (degree >= 79)
            degree--;
        return degree;
    } else {
        return kHaierAcYrw02MinTempC + pHaier->ac176.Temp;
    }
}

/**
 * @brief 设置海尔YRW02型号空调的温度
 * @param pAC 空调设备指针
 * @param degrees 目标温度值（根据当前单位自动处理摄氏度/华氏度）
 * @return 实际设置的温度值（可能因范围限制被调整）
 */
static uint8_t haier_acyrw02_set_temp(pAir_conditioner_t pAC, const uint8_t degrees)
{
    pHaierAcYrw02_t pHaier = (pHaierAcYrw02_t)pAC;
    uint8_t old_temp = haier_acyrw02_get_temp(pAC);

    if (old_temp == degrees) {
        return old_temp;
    }

    bool current_fahrenheit = pHaier->ac176.UseFahrenheit;

    // // 设置温度调节按键
    // pHaier->ac176.Button = (old_temp > degrees) ?
    //                            kHaierAcYrw02ButtonTempDown :
    //                            kHaierAcYrw02ButtonTempUp;

    uint8_t temp = degrees;
    if (current_fahrenheit) {
        // 华氏度范围限制
        if (temp < kHaierAcYrw02MinTempF)
            temp = kHaierAcYrw02MinTempF;
        else if (temp > kHaierAcYrw02MaxTempF)
            temp = kHaierAcYrw02MaxTempF;

        // 特殊温度补偿
        uint8_t adjusted_temp = temp;
        if (temp >= 77)
            adjusted_temp++;
        if (temp >= 79)
            adjusted_temp++;

        pHaier->ac176.ExtraDegreeF = adjusted_temp % 2;
        pHaier->ac176.Temp = (adjusted_temp - kHaierAcYrw02MinTempF - pHaier->ac176.ExtraDegreeF) >> 1;
    } else {
        // 摄氏度范围限制
        if (temp < kHaierAcYrw02MinTempC)
            temp = kHaierAcYrw02MinTempC;
        else if (temp > kHaierAcYrw02MaxTempC)
            temp = kHaierAcYrw02MaxTempC;

        pHaier->ac176.Temp = temp - kHaierAcYrw02MinTempC;
    }

    return haier_acyrw02_get_temp(pAC);
}

// 电源控制
static uint8_t haier_acyrw02_set_power(pAir_conditioner_t pAC, const uint8_t on)
{
    if (!pAC)
        return 0;
    pHaierAcYrw02_t pHaier = (pHaierAcYrw02_t)pAC;

    pHaier->ac176.Button = kHaierAcYrw02ButtonPower;
    pHaier->ac176.Power = (on != 0); // 非0值视为开启
    return pHaier->ac176.Power;
}

static uint8_t haier_acyrw02_get_power(pAir_conditioner_t pAC)
{
    if (!pAC)
        return 0;
    pHaierAcYrw02_t pHaier = (pHaierAcYrw02_t)pAC;
    return pHaier->ac176.Power ? 1 : 0;
}

// 运行模式
static uint8_t haier_acyrw02_set_mode(pAir_conditioner_t pAC, const uint8_t mode)
{
    if (!pAC)
        return kHaierAcYrw02Auto;
    pHaierAcYrw02_t pHaier = (pHaierAcYrw02_t)pAC;

    // 验证模式有效性
    uint8_t new_mode;
    switch (mode) {
        case kHaierAcYrw02Auto:
        case kHaierAcYrw02Dry:
        case kHaierAcYrw02Fan:
        case kHaierAcYrw02Cool:
        case kHaierAcYrw02Heat:
            new_mode = mode;
            break;
        default:
            new_mode = kHaierAcYrw02Auto; // 默认自动模式
    }

    // 自动/除湿/风扇模式下关闭Turbo和Quiet
    if (new_mode != kHaierAcYrw02Cool && new_mode != kHaierAcYrw02Heat) {
        pHaier->ac176.Turbo = false;
        pHaier->ac176.Quiet = false;
    }

    pHaier->ac176.Button = kHaierAcYrw02ButtonMode;
    pHaier->ac176.Mode = new_mode;
    return new_mode;
}

static uint8_t haier_acyrw02_get_mode(pAir_conditioner_t pAC)
{
    if (!pAC)
        return kHaierAcYrw02Auto;
    pHaierAcYrw02_t pHaier = (pHaierAcYrw02_t)pAC;
    return pHaier->ac176.Mode;
}

// 风速控制
static uint8_t haier_acyrw02_set_fan(pAir_conditioner_t pAC, const uint8_t speed)
{
    if (!pAC)
        return kHaierAcYrw02FanAuto;
    pHaierAcYrw02_t pHaier = (pHaierAcYrw02_t)pAC;

    // 验证风速有效性
    switch (speed) {
        case kHaierAcYrw02FanLow:
        case kHaierAcYrw02FanMed:
        case kHaierAcYrw02FanHigh:
        case kHaierAcYrw02FanAuto:
            pHaier->ac176.Fan = speed;
            pHaier->ac176.Fan2 = (speed == kHaierAcYrw02FanAuto) ? 0 : speed;
            pHaier->ac176.Button = kHaierAcYrw02ButtonFan;
            return speed;
        default:
            return pHaier->ac176.Fan; // 无效值返回当前风速
    }
}

static uint8_t haier_acyrw02_get_fan(pAir_conditioner_t pAC)
{
    if (!pAC)
        return kHaierAcYrw02FanAuto;
    pHaierAcYrw02_t pHaier = (pHaierAcYrw02_t)pAC;
    return pHaier->ac176.Fan;
}

// 扩展功能（健康、睡眠、Turbo、静音、锁定、扫风等）
static uint8_t haier_acyrw02_set_extend(pAir_conditioner_t pAC, const uint8_t extend, uint8_t data)
{
    if (!pAC)
        return 0;
    pHaierAcYrw02_t pHaier = (pHaierAcYrw02_t)pAC;
    bool enable = (data != 0);

    switch (extend) {
        case HAIER_EXTEND_HEALTH:
            pHaier->ac176.Button = kHaierAcYrw02ButtonHealth;
            pHaier->ac176.Health = enable;
            break;
        case HAIER_EXTEND_SLEEP:
            pHaier->ac176.Button = kHaierAcYrw02ButtonSleep;
            pHaier->ac176.Sleep = enable;
            break;
        case HAIER_EXTEND_TURBO:
            // 仅在制冷/制热模式有效
            if (pHaier->ac176.Mode == kHaierAcYrw02Cool ||
                pHaier->ac176.Mode == kHaierAcYrw02Heat) {
                pHaier->ac176.Button = kHaierAcYrw02ButtonTurbo;
                pHaier->ac176.Turbo = enable;
                if (enable)
                    pHaier->ac176.Quiet = false;
            }
            break;
        case HAIER_EXTEND_QUIET:
            // 仅在制冷/制热模式有效
            if (pHaier->ac176.Mode == kHaierAcYrw02Cool ||
                pHaier->ac176.Mode == kHaierAcYrw02Heat) {
                pHaier->ac176.Button = kHaierAcYrw02ButtonTurbo;
                pHaier->ac176.Quiet = enable;
                if (enable)
                    pHaier->ac176.Turbo = false;
            }
            break;
        case HAIER_EXTEND_LOCK:
            pHaier->ac176.Button = kHaierAcYrw02ButtonLock;
            pHaier->ac176.Lock = enable;
            break;
        case HAIER_EXTEND_SWINGV:
            // data表示具体扫风模式（0=关闭，1=自动，2=上，3=中，4=下等）
            pHaier->ac176.Button = kHaierAcYrw02ButtonSwingV;
            pHaier->ac176.SwingV = data;
            break;
        case HAIER_EXTEND_SWINGH:
            // data表示具体扫风模式（0=关闭，1=自动，2=左，3=中，4=右等）
            pHaier->ac176.Button = kHaierAcYrw02ButtonSwingH;
            pHaier->ac176.SwingH = data;
            break;
        default:
            return 0; // 不支持的扩展功能
    }
    return 1; // 成功设置
}

static uint8_t haier_acyrw02_get_extend(pAir_conditioner_t pAC)
{
    if (!pAC)
        return 0;
    pHaierAcYrw02_t pHaier = (pHaierAcYrw02_t)pAC;
    uint8_t result = 0;

    // 组合各扩展功能状态（1=开启，0=关闭）
    if (pHaier->ac176.Health)
        result |= HAIER_EXTEND_HEALTH;
    if (pHaier->ac176.Sleep)
        result |= HAIER_EXTEND_SLEEP;
    if (pHaier->ac176.Turbo)
        result |= HAIER_EXTEND_TURBO;
    if (pHaier->ac176.Quiet)
        result |= HAIER_EXTEND_QUIET;
    if (pHaier->ac176.Lock)
        result |= HAIER_EXTEND_LOCK;

    return result;
}

static rmt_symbol_word_t *haier_acyrw02_send(pAir_conditioner_t pAC, size_t *len)
{
    if (!pAC || !len)
        return NULL;
    pHaierAcYrw02_t pHaier = (pHaierAcYrw02_t)pAC;
    // 发送前计算校验和（模拟IRHaierAC176::checksum()）
    pHaier->ac176.raw[kHaierACYRW02StateLength - 1] =
        sumBytes(pHaier->ac176.raw, kHaierACYRW02StateLength - 1,0);
    pHaier->ac176.raw[kHaierAC176StateLength - 1] =
        sumBytes(pHaier->ac176.raw + kHaierACYRW02StateLength,
                 kHaierAC176StateLength - kHaierACYRW02StateLength - 1,0);
    /*编码，把数据转换成rmt数据*/
    uint32_t cnt=0,i=0;
    //头部 3000μs 高 + 3000μs 低 + 3000μs 高 + 4300μs 低
    for (i = 0;i<2;i++)
    {
        out_symbols[cnt].duration0 = 3000;
        out_symbols[cnt].level0 = 1;
        out_symbols[cnt].duration1 = 3000;
        out_symbols[cnt].level1 = 0;
        cnt++;
    }
    /*补4300μs*/
    out_symbols[cnt].duration0 = (4300 - 3000)/2;
    out_symbols[cnt].level0 = 0;
    out_symbols[cnt].duration1 = (4300 - 3000) / 2;
    out_symbols[cnt].level1 = 0;
    cnt++;

    // 发送协议数据：将空调状态数据转换为红外符号（RMT格式）
    // 数据位定义：
    // - 逻辑0：520μs 高电平 + 650μs 低电平
    // - 逻辑1：520μs 高电平 + 1650μs 低电平
    // 位序：按字节的MSB（最高位）到LSB（最低位）顺序处理
    for (int i = 0; i < kHaierAC176StateLength; i++) {
        uint8_t current_byte = pHaier->ac176.raw[i]; // 当前待处理的字节
        // 逐位处理（8位，从最高位bit7到最低位bit0）
        for (int bit_pos = 0; bit_pos < 8; bit_pos++) {
            // 提取当前位（MSB优先：bit7 -> bit0，通过0x80右移bit_pos实现）
            bool is_bit_set = (current_byte & (0x80 >> bit_pos)) != 0;

            // 统一设置高电平参数（两种逻辑的高电平部分相同）
            out_symbols[cnt].level0 = 1;      // 高电平
            out_symbols[cnt].duration0 = 520; // 高电平持续520μs（1MHz分辨率下单位为μs）

            // 根据位值设置低电平持续时间
            if (is_bit_set) {
                out_symbols[cnt].duration1 = 1650; // 逻辑1：低电平1650μs
            } else {
                out_symbols[cnt].duration1 = 650; // 逻辑0：低电平650μs
            }
            out_symbols[cnt].level1 = 0; // 低电平（两种逻辑的低电平部分相同）

            cnt++; // 移动到下一个符号
        }
    }
    //- 结束信号：`520μs 高 + 150000μs 低
    out_symbols[cnt].duration0 = 520;
    out_symbols[cnt].level0 = 1;
    out_symbols[cnt].duration1 = 0x49F4; //150000μs-131068μs
    out_symbols[cnt].level1 = 0;
    cnt++;
    //150000μs
    for (i = 0; i < 2; i++) //131068
    {
        out_symbols[cnt].duration0 = 0x7fff;
        out_symbols[cnt].level0 = 0;
        out_symbols[cnt].duration1 = 0x7fff;
        out_symbols[cnt].level1 = 0;
        cnt++;
    }
    // 结束符,要有这个才能结束发送返回空闲状态
    out_symbols[cnt].duration0 = 0;
    out_symbols[cnt].level0 = 0;
    out_symbols[cnt].duration1 = 0;
    out_symbols[cnt].level1 = 0;
    cnt++;
    *len=cnt;
    return out_symbols;
}

static void haier_acyrw02_del(pAir_conditioner_t pAC)
{
    if (pAC) {
        free(pAC);
    }
    // 清理资源
    if (out_symbols) {
        free(out_symbols); // 释放符号数据内存
    }
    }

pAir_conditioner_t haier_acyrw02_init(void)
{
    pHaierAcYrw02_t haier_acyrw02 = (pHaierAcYrw02_t)malloc(sizeof(HaierAcYrw02_t));
    if (!haier_acyrw02)
        return NULL;

    // 初始化空调控制接口
    haier_acyrw02->ac.ir_protocol = HAIER_YRW02_PROTOCOL;
    haier_acyrw02->ac.set_temp = haier_acyrw02_set_temp;
    haier_acyrw02->ac.get_temp = haier_acyrw02_get_temp;
    haier_acyrw02->ac.set_power = haier_acyrw02_set_power;
    haier_acyrw02->ac.get_power = haier_acyrw02_get_power;
    haier_acyrw02->ac.set_mode = haier_acyrw02_set_mode;
    haier_acyrw02->ac.get_mode = haier_acyrw02_get_mode;
    haier_acyrw02->ac.set_fan = haier_acyrw02_set_fan;
    haier_acyrw02->ac.get_fan = haier_acyrw02_get_fan;
    haier_acyrw02->ac.set_extend = haier_acyrw02_set_extend;
    haier_acyrw02->ac.get_extend = haier_acyrw02_get_extend;
    haier_acyrw02->ac.send = haier_acyrw02_send;
    haier_acyrw02->ac.del = haier_acyrw02_del;

    // 初始化协议数据
    haier_acyrw02->ac176.Model = kHaierAcYrw02ModelA;
    haier_acyrw02->ac176.Prefix2 = kHaierAc176Prefix;
    haier_acyrw02->ac176.Temp = kHaierAcYrw02DefTempC - kHaierAcYrw02MinTempC;
    haier_acyrw02->ac176.ExtraDegreeF = 0;
    haier_acyrw02->ac176.UseFahrenheit = false;
    haier_acyrw02->ac176.Health = true;
    haier_acyrw02->ac176.Fan = kHaierAcYrw02FanAuto;
    haier_acyrw02->ac176.Fan2 = 0;
    haier_acyrw02->ac176.Power = true;
    haier_acyrw02->ac176.Button = kHaierAcYrw02ButtonPower;
    haier_acyrw02->ac176.Mode = kHaierAcYrw02Auto;
    haier_acyrw02->ac176.Sleep = false;
    haier_acyrw02->ac176.Turbo = false;
    haier_acyrw02->ac176.Quiet = false;
    haier_acyrw02->ac176.SwingV = 0;
    haier_acyrw02->ac176.SwingH = 0;
    haier_acyrw02->ac176.TimerMode = 0;
    haier_acyrw02->ac176.OnTimerHrs = 0;
    haier_acyrw02->ac176.OnTimerMins = 0;
    haier_acyrw02->ac176.OffTimerHrs = 0;
    haier_acyrw02->ac176.OffTimerMins = 0;
    haier_acyrw02->ac176.Lock = false;

    // 分配符号数据内存
    out_symbols = (rmt_symbol_word_t *)malloc((kHaierAC176Bits + HAIER_ACYRW02_HEAD_AND_TAIL_SYMBOLS) * sizeof(rmt_symbol_word_t));
    return &haier_acyrw02->ac;
}